<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ViewErrorBag;

class JsonReturn
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $this->fixRequest($request);
        /**@var \Illuminate\Http\Response $result**/
        $result = $next($request);
        $status = intval($result->status());
        if ($status !== 200) {
            $methodName = "handle$status";
            return method_exists($this, $methodName) ?
                call_user_func([$this, $methodName], $result) :
                $this->handleError($result);
        } else {
            $return_data = $result->getOriginalContent();
            if (is_null($return_data)) {
                $return_data = [];
            }
    //        if (!is_array($return_data)) $return_data = [$return_data];
            if (isset($return_data['error_msg'])) {
                $res = [
                    'success' => false,
                    'message' => $return_data['error_msg'],
                ];
            } else {
                $res = [
                    'success' => true,
                    'data' => $return_data,
                ];
            }
            return Response::json($res);
        }
    }

    /**
     * 特殊情况下, 修复request中json解析失败的问题
     * @param Request $request
     *
     */
    protected function fixRequest(Request &$request)
    {
            $raw = urldecode(file_get_contents('php://input'));
            $data = json_decode(substr($raw, 1), true);
            if (count($data) > 0) {
                $request->merge($data);
            }
    }

    protected function handle422(JsonResponse $jsonResponse) {
        $data = $jsonResponse->getData();
        $success = false;
        $message = '';
        foreach($data as $k => $v) {
            if (!empty($message)) $message .= ', ';
            if (is_array($v)) {
                $message .= join(',', $v);
            } else if (is_string($v)) {
                $message .= "$v";
            }
        }
        return Response::json(compact('success', 'message'), 422);
    }

    protected function handle302($response) {
        /** @var ViewErrorBag $errors */
        $errors = session('errors');
        $msgs = $errors->default->all();
        $success = false;
        $message = implode(',', $msgs);
        return Response::json(compact('success', 'message'), 422);
    }

    protected function handleError(\Illuminate\Http\Response $response) {
        $exceptionHandle = $response->exception;
        $success = false;
        $exception = [
           'file' => $exceptionHandle->getFile(),
           'line' => $exceptionHandle->getLine(),
           'error_msg' => $exceptionHandle->getMessage(),
        ];
        $message = $exceptionHandle->getMessage();
        $return_data = compact('success', 'message');
        if ( config('app.debug') ) {
            $message = $response->status();
            $return_data = compact('success', 'message', 'exception');
        }
        return Response::json($return_data, $response->getStatusCode());
    }
}
